package com.pt25.base.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 1、Spring Boot项目中统一处理传入对象中的所有String字段，确保它们在反序列化时自动进行trim处理
 * 2、统一处理处理时间序列化方式
 */
@Configuration
public class JacksonConfig {

    public final static ObjectMapper objectMapper = new ObjectMapper();

    static {
        //在序列化对象时忽略值为 null 的属性。意味着如果某个字段的值为 null，该字段将不会出现在序列化后的 JSON 中。
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //Jackson 在反序列化时如果遇到 JSON 中存在而目标 Java 对象中不存在的字段，会抛出 UnrecognizedPropertyException 异常。配置 FAIL_ON_UNKNOWN_PROPERTIES 为 false 可以让 Jackson 在反序列化时忽略未知属性，不抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // Jackson 在序列化时如果遇到 JSON 中存在而目标 Java 对象为空，防止序列化报错，并不序列化空对象
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        //字符类型返序列化trim处理
        objectMapper.registerModule(new TrimModule());
        //解决序列化java.time.LocalDateTime类型时遇到问题
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
        objectMapper.registerModule(javaTimeModule);
    }

    @Bean
    public ObjectMapper objectMapper() {
        return objectMapper;
    }

    static class TrimModule extends SimpleModule {
        public TrimModule() {
            this.addDeserializer(String.class, new JsonDeserializer<>() {
                @Override
                public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
                    String value = jsonParser.getText();
                    return value != null ? value.trim() : null;
                }
            });
        }
    }
}


